package com.yuandian.business.monitor.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yuandian.api.business_monitor.IndicatorObjEnum;
import com.yuandian.api.business_monitor.po.AlarmParams;
import com.yuandian.api.business_monitor.vo.AlarmIndicatorsVo;
import com.yuandian.api.business_monitor.vo.AlarmProportionCopyVo;
import com.yuandian.api.business_monitor.vo.AlarmProportionVo;
import com.yuandian.api.management.entity.ConfAlarmIndicators;
import com.yuandian.api.management.entity.ConfStep;
import com.yuandian.api.management.feign.RemoteAlarmIndicatorsService;
import com.yuandian.api.management.feign.RemoteStepService;
import com.yuandian.bpm.common.core.util.R;
import com.yuandian.business.monitor.mapper.BusiAlarmMapper;
import com.yuandian.business.monitor.service.BusiAlarmService;
import com.yuandian.utils.PageDataInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 告警信息服务类
 *
 * @author LinShiHe
 * @since 2021-05-27
 */
@Service
@Slf4j
public class BusiAlarmServiceImpl implements BusiAlarmService {

	@Autowired
	private BusiAlarmMapper busiAlarmMapper;

	@Autowired
	private RemoteAlarmIndicatorsService remoteAlarmIndicatorsService;
	@Autowired
	private RemoteStepService remoteStepService;

	/**
	 * 对应字典sys_dict_type里面的类型sys_alarm_indicator_obj_type
	 * 1为系统，2为业务，3为网端，4为步骤
	 */
	private final int systemObjType  = 1;
	private final int businessObjType = 2;
	private final int segmentObjType = 3;
	/**
	 * 按照系统ID、业务编码及时间范围分类统计各类型告警（告警类型环形图）
	 *
	 * @param params 查询参数
	 * @return 返回通用结果集
	 */
	@Override
	public List<AlarmProportionVo> getBusinessAlarmPercent(AlarmParams params) {
		// 1、获取表信息集

		// 4、执行查询
		List<AlarmProportionVo> list = busiAlarmMapper.queryBusinessAlarmTypePercent(params, "ads_busi_alarm_trend_m");
		// 5、返回结果集
		return list;
	}

	/**
	 * 按照系统ID、业务编码及时间范围分类统计各等级告警（告警等级环形图）
	 *
	 * @param params 查询参数
	 * @return 返回通用结果集
	 */
	@Override
	public List<AlarmProportionVo> getBusinessAlarmLevelPercent(AlarmParams params) {

		// 4、执行查询
		List<AlarmProportionVo> list = busiAlarmMapper.queryBusinessAlarmLevelPercent(params, "ads_busi_alarm_trend_m");
		// 5、返回结果集
		return list;
	}

	/**
	 * 查询告警指标 code_id 值
	 *
	 * @return 返回分页对象
	 */
	public List<Map<String, Integer>> queryBaseIndicatorsCodeId() {
		R r = remoteAlarmIndicatorsService.getBaseAlarmIndicatorsAndCode();
		if(r.getCode() != 0){
			throw new RuntimeException("调用配置平台查询告警指标错误！");
		}
		return (List<Map<String, Integer>>)r.getData();
	}

	/**
	 * 按照系统ID、业务编码、时间范围、端口ID查询各告警对应不同等级的告警总数
	 *
	 * @param params 查询参数（系统ID、业务编码、时间范围、端口ID）
	 * @return 返回通用结果集
	 */
	@Override
	public PageDataInfo getBusinessGradeDate(AlarmParams params) {

		// 4、设置分页对象，如果不传pageNum或pageSize，相当于不分页
		Page<AlarmProportionVo> page = null;
		if (params.getPageNum() > 0 && params.getPageSize() > 0) {
			page = new Page<>(params.getPageNum(), params.getPageSize());
		}
		// 5、执行查询
		List<AlarmProportionVo> list = busiAlarmMapper.queryBusinessGradeDate(page, params, "ads_busi_alarm_trend_m");
		// 6、转换业务数据
		List<Map<String, Integer>> codeList = queryBaseIndicatorsCodeId();
		Map<Integer, Integer> map = new HashMap<>();
		for (Map<String, Integer> codeMap : codeList) {
			map.put(codeMap.get("id"), codeMap.get("code"));
		}
		list.forEach(alarmProportionVo -> {
			if (alarmProportionVo.getLatestAlarmTime() != null && !("").equals(alarmProportionVo.getLatestAlarmTime())) {
				alarmProportionVo.setLatestAlarmTime(alarmProportionVo.getLatestAlarmTime().replace(".0", ""));
			}
			if (map.get(alarmProportionVo.getAlarmTypeId()) != null) {
				if (map.get(alarmProportionVo.getAlarmTypeId()) == 36
						|| map.get(alarmProportionVo.getAlarmTypeId()) == 37
						|| map.get(alarmProportionVo.getAlarmTypeId()) == 38) {
					alarmProportionVo.setCategory("APM");
				} else {
					alarmProportionVo.setCategory("BPM");
				}
			}

			alarmProportionVo.setAlarmState(params.getAlarmState());

		});
		// 7、返回分页对象
		if (page == null) {
			return new PageDataInfo(list.size(), list);
		}
		return new PageDataInfo(page, list);
	}

	/**
	 * 按照系统ID、业务编码、时间范围、端口ID和告警类型id查询各告警详情列表
	 *
	 * @param params 查询参数（系统ID、业务编码、时间范围、端口ID、告警类型id）
	 * @return 返回通用结果集
	 */
	@Override
	public PageDataInfo getBusinessAlarmList(@RequestBody AlarmParams params) {

		// 4、设置分页对象，如果不传pageNum或pageSize，相当于不分页
		Page<AlarmProportionCopyVo> page = null;
		if (params.getPageNum() > 0 && params.getPageSize() > 0) {
			page = new Page<>(params.getPageNum(), params.getPageSize());
		}
		// 5、执行查询
		List<AlarmProportionCopyVo> list = busiAlarmMapper.queryBusinessAlarmList(page, params, "ads_busi_alarm_trend_m");
		// 6、转换业务数据
		list.forEach(alarmProportionVo -> {
			if (alarmProportionVo.getStartTime() != null && !("").equals(alarmProportionVo.getStartTime())
					&& alarmProportionVo.getEndTime() != null && !("").equals(alarmProportionVo.getEndTime())) {
				alarmProportionVo.setStartTime(alarmProportionVo.getStartTime().replace(".0", ""));
				alarmProportionVo.setEndTime(alarmProportionVo.getEndTime().replace(".0", ""));
			}
		});
		// 7、返回分页对象
		if (page == null) {
			return new PageDataInfo(list.size(), list);
		}
		return new PageDataInfo(page, list);
	}

	/**
	 * 查询基础指标列表
	 *
	 * @return 返回通用结果集
	 */
	@Override
	public PageDataInfo queryBaseIndicatorsList(@RequestBody AlarmParams params) {

		params.setOrderByColumn(null);
		params.setIsAsc(null);
		// 4、设置分页对象，如果不传pageNum或pageSize，相当于不分页
		Page<AlarmProportionVo> page = null;
		if (params.getPageNum() > 0 && params.getPageSize() > 0) {
			page = new Page<>(params.getPageNum(), params.getPageSize());
		}
		// 5、执行查询
		ConfAlarmIndicators confAlarmIndicators = new ConfAlarmIndicators();
		confAlarmIndicators.setType(1);
		List<ConfAlarmIndicators> indicatorList = remoteAlarmIndicatorsService.list(confAlarmIndicators).getData();
		List<Integer> ids = indicatorList.stream().map(ConfAlarmIndicators::getId).collect(Collectors.toList());
		params.setAlarmTypeIds(ids);
		List<AlarmProportionVo> alarmProportionVoList = busiAlarmMapper.queryAlarmIndicatorExist(page, params, "ads_busi_alarm_trend_m");
		List<Integer> dbIds = alarmProportionVoList
				.stream()
				.map(AlarmProportionVo::getAlarmTypeId)
				.collect(Collectors.toList());
		List<ConfAlarmIndicators> list = indicatorList
				.stream()
				.filter(indicator -> dbIds.contains(indicator.getId()))
				.collect(Collectors.toList());
		// 6、转换业务数据
		return new PageDataInfo(page, list);
	}

	/**
	 * 按照系统ID、业务编码及时间范围分类统计各类型告警（告警类型环形图---业务监控详情页面）
	 *
	 * @param params 查询参数
	 * @return 返回通用结果集
	 */
	@Override
	public List<AlarmProportionVo> getBusinessMonitorAlarmPercent(AlarmParams params) {


		List<AlarmProportionVo> res = new ArrayList<>();

		res = busiAlarmMapper.queryBusinessMonitorAlarmTypePercent(params);

		return res;
	}

	@Override
	public R checkExpression(AlarmIndicatorsVo indicator) {
		String expressionStr = "";
		try {
			Date now = new Date();
			SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");

			// 对应字典sys_dict_type里面的类型sys_alarm_indicator_obj_type
			// 1为系统，2为业务，3为网端，4为步骤
			if (indicator.getObjId() != null) {
				if (indicator.getObjId().intValue() == this.systemObjType) {
					String tableName = IndicatorObjEnum.system.getTableName();
					String group = IndicatorObjEnum.system.getGroupByCondition();
					expressionStr = " (" + indicator.getExpression() + ") as a from " + tableName
							+ " where 1=2 group by " + group;
				} else if (indicator.getObjId().intValue() == this.businessObjType) {
					String tableName = IndicatorObjEnum.business.getTableName();
					String group = IndicatorObjEnum.business.getGroupByCondition();
					expressionStr = " (" + indicator.getExpression() + ") as a from " + tableName
							+ " where 1=2 group by " + group;
				} else if (indicator.getObjId().intValue() == this.segmentObjType) {
					String tableName = IndicatorObjEnum.segment.getTableName();
					String group = IndicatorObjEnum.segment.getGroupByCondition();
					expressionStr = " (" + indicator.getExpression() + ") as a from " + tableName
							+ " where 1=2 group by " + group;
				}
			}

			busiAlarmMapper.checkExpression(expressionStr);
		} catch (Exception e) {
			log.info("告警指标表达式校验不通过：" + "select " + expressionStr);
			e.printStackTrace();
			return R.failed("表达式验证不通过,无法新增!");
		}
		return R.ok();
	}

}
